// src/main/java/com/fjnu/dao/impl/UserDaoImpl.java
package com.fjnu.dao.impl;

import com.fjnu.dao.UserDao;
import com.fjnu.dto.UserConditionDto;
import com.fjnu.entity.User;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserDaoImpl implements UserDao {

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public int insert(User newUser) {
        String sql = "INSERT INTO tb_user(name, password, salt, email, gender, score, status, create_time) " +
                "VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
        return jdbcTemplate.update(sql, newUser.getName(), newUser.getPassword(), newUser.getSalt(),
                newUser.getEmail(), newUser.getGender(), newUser.getScore(), newUser.getStatus(),
                newUser.getCreateTime());
    }

    @Override
    public int insertUserRole(Integer userId, Integer roleId) {
        String sql = "INSERT INTO tb_user_role(user_id, role_id) VALUES(?, ?)";
        return jdbcTemplate.update(sql, userId, roleId);
    }

    @Override
    public int batchInsertUserRoles(Integer userId, List<Integer> roleIds) {
        String sql = "INSERT INTO tb_user_role(user_id, role_id) VALUES(?, ?)";
        List<Object[]> batchArgs = new ArrayList<>();
        for (Integer roleId : roleIds) {
            batchArgs.add(new Object[]{userId, roleId});
        }
        int[] result = jdbcTemplate.batchUpdate(sql, batchArgs);
        return result.length;
    }

    @Override
    public int updatePassword(Integer userId, String newPassword) {
        String sql = "UPDATE tb_user SET password = ? WHERE user_id = ?";
        return jdbcTemplate.update(sql, newPassword, userId);
    }

    @Override
    public int updateScore(Integer userId, Long incrementedScore) {
        String sql = "UPDATE tb_user SET score = score + ? WHERE user_id = ?";
        return jdbcTemplate.update(sql, incrementedScore, userId);
    }

    @Override
    public User selectByNameAndPwd(String username, String password) {
        String sql = "SELECT * FROM tb_user WHERE name = ? AND password = ?";
        try {
            return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), username, password);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public List<User> selectByCondition(UserConditionDto userCondition) {
        StringBuilder sql = new StringBuilder("SELECT * FROM tb_user WHERE 1=1");
        List<Object> params = new ArrayList<>();

        if (userCondition.getUsername() != null && !userCondition.getUsername().isEmpty()) {
            sql.append(" AND name LIKE ?");
            params.add("%" + userCondition.getUsername() + "%");
        }
        if (userCondition.getEmail() != null && !userCondition.getEmail().isEmpty()) {
            sql.append(" AND email LIKE ?");
            params.add("%" + userCondition.getEmail() + "%");
        }
        if (userCondition.getPhone() != null && !userCondition.getPhone().isEmpty()) {
            sql.append(" AND phone LIKE ?");
            params.add("%" + userCondition.getPhone() + "%");
        }
        if (userCondition.getStatus() != null) {
            sql.append(" AND status = ?");
            params.add(userCondition.getStatus());
        }
        if (userCondition.getMinScore() != null) {
            sql.append(" AND score >= ?");
            params.add(userCondition.getMinScore());
        }
        if (userCondition.getMaxScore() != null) {
            sql.append(" AND score <= ?");
            params.add(userCondition.getMaxScore());
        }

        try {
            return jdbcTemplate.query(sql.toString(), new BeanPropertyRowMapper<>(User.class), params.toArray());
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public List<User> selectByConditionWithLimit(UserConditionDto userCondition, Integer startIndex, Integer endIndex) {
        List<User> allUsers = selectByCondition(userCondition);
        if (allUsers == null || allUsers.isEmpty()) {
            return null;
        }

        int fromIndex = Math.min(startIndex, allUsers.size());
        int toIndex = Math.min(endIndex, allUsers.size());

        if (fromIndex >= toIndex) {
            return null;
        }

        return allUsers.subList(fromIndex, toIndex);
    }
}